﻿namespace dogd
{
	using System.Collections.Generic;

	/// <summary>
	/// Interface representing a repository or database.
	/// </summary>
	public interface IRepository
	{
		/// <summary>
		/// Creates a new repository using the supplied sql script.
		/// </summary>
		/// <param name="sqlText"></param>
		void CreateNewRepository(string sqlText);

		/// <summary>
		/// Insert a new instance of an object int the repository
		/// </summary>
		/// <typeparam name="T"></typeparam>
		/// <param name="newInstance"></param>
		/// <returns></returns>
		[System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Design", "CA1004:GenericMethodsShouldProvideTypeParameter", Justification = "As intended")]
		void Add<T>(T newInstance) where T : new();

		/// <summary>
		/// Read a single object identified by an identifiable guid field
		/// </summary>
		/// <typeparam name="T"></typeparam>
		/// <param name="guid"></param>
		/// <returns></returns>
		[System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Design", "CA1004:GenericMethodsShouldProvideTypeParameter", Justification = "As intended")]
		T Read<T>(string guid) where T : new();

		/// <summary>
		/// Read a single object identified by a key object
		/// </summary>
		/// <typeparam name="T"></typeparam>
		/// <param name="primaryKey"></param>
		/// <returns></returns>
		[System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Design", "CA1004:GenericMethodsShouldProvideTypeParameter", Justification = "As intended")]
		T Read<T>(Key primaryKey) where T : new();

		/// <summary>
		/// Read all items of a type in the repository
		/// </summary>
		/// <typeparam name="T"></typeparam>
		/// <returns></returns>
		[System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Design", "CA1004:GenericMethodsShouldProvideTypeParameter", Justification = "As intended")]
		ICollection<T> ReadAll<T>() where T : new();

		/// <summary>
		/// Read all items of a type in the repository matching filter
		/// </summary>
		/// <typeparam name="T"></typeparam>
		/// <returns></returns>
		[System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Design", "CA1004:GenericMethodsShouldProvideTypeParameter", Justification = "As intended")]
		ICollection<T> ReadAll<T>(FilterByCollection filters) where T : new();

		/// <summary>
		/// Find all items of a type in the repository containing search term
		/// </summary>
		/// <typeparam name="T"></typeparam>
		/// <returns></returns>
		[System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Design", "CA1004:GenericMethodsShouldProvideTypeParameter", Justification = "As intended")]
		ICollection<T> Search<T>(string searchTerm) where T : new();

		/// <summary>
		/// Read all items of a type given a foreign key in the repository
		/// </summary>
		/// <typeparam name="T"></typeparam>
		/// <param name="foreignKey"></param>
		/// <returns></returns>
		[System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Design", "CA1004:GenericMethodsShouldProvideTypeParameter", Justification = "As intended")]
		ICollection<T> ReadAll<T>(Key foreignKey) where T : new();

		/// <summary>
		/// Update an existing instance. Expects the key to be valid
		/// </summary>
		/// <typeparam name="T"></typeparam>
		/// <param name="existingInstance"></param>
		[System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Design", "CA1004:GenericMethodsShouldProvideTypeParameter", Justification = "As intended")]
		void Update<T>(T existingInstance) where T : new();

		/// <summary>
		/// Remove the specified object from the db
		/// </summary>
		/// <typeparam name="T"></typeparam>
		/// <param name="primaryKey"></param>
		[System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Design", "CA1004:GenericMethodsShouldProvideTypeParameter", Justification = "As intended")]
		void Remove<T>(Key primaryKey) where T : new();

		/// <summary>
		/// Remove all items of a type given a foreign key in the repository
		/// </summary>
		/// <typeparam name="T"></typeparam>
		/// <returns></returns>
		[System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Design", "CA1004:GenericMethodsShouldProvideTypeParameter", Justification = "As intended")]
		void RemoveAll<T>(Key foreignKey) where T : new();
	}
}
